﻿using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

namespace Game
{
    [RequireComponent(typeof(Collider2D))]
    public class Collider : MonoBehaviour
    {
        [SerializeField] private ContactFilter2D ContactFilter;

        public ContactFilter2D Filter
        {
            get
            {
                return ContactFilter;
            }
        }
        protected Collider2D mCollider;
        
        private Dictionary<Collider2D,bool> mColliderDic;
        private List<Collider2D> mColliderAddList;
        private List<Collider2D> mColliderRemoveList;
        private List<Collider2D> mColliderResults;

        protected virtual void Awake()
        {
            mColliderDic = new Dictionary<Collider2D,bool>();
            mColliderAddList = new List<Collider2D>();
            mColliderRemoveList = new List<Collider2D>();
            mColliderResults = new List<Collider2D>();
        }

        protected virtual void Start()
        {
            mCollider = GetComponent<Collider2D>();
        }

        protected virtual void Update()
        {
            onCollisionExecute();
        }

        private void onCollisionExecute()
        {
            int num = mCollider.OverlapCollider(ContactFilter, mColliderResults);
            foreach (var collider in mColliderResults)
            {
                if (!mColliderDic.ContainsKey(collider))
                {
                    mColliderAddList.Add(collider);
                } else
                {
                    mColliderDic[collider] = true;
                }
            }
            for (int i = 0;i < mColliderDic.Count; ++i)
            {
                if (!mColliderDic.ElementAt(i).Value)
                {
                    mColliderRemoveList.Add(mColliderDic.ElementAt(i).Key);
                } else
                {
                    onColliderStay(mColliderDic.ElementAt(i).Key);
                    mColliderDic[mColliderDic.ElementAt(i).Key] = false;
                }
            }
            
            for (int i = 0; i < mColliderRemoveList.Count; ++i)
            {
                mColliderDic.Remove(mColliderRemoveList[i]);
                onColliderExit(mColliderRemoveList[i]);
            }

            mColliderRemoveList.Clear();
            for (int i = 0; i < mColliderAddList.Count; ++i)
            {
                if (mColliderDic.ContainsKey(mColliderAddList[i])) {
                    continue;
                }
                mColliderDic.Add(mColliderAddList[i],false);
                onColliderEnter(mColliderAddList[i]);
            }

            mColliderAddList.Clear();
        }
        
        
        protected virtual void onColliderEnter(Collider2D collider) { }

        protected virtual void onColliderStay(Collider2D collider) { }
        
        protected virtual void onColliderExit(Collider2D collider) { }
    }
}